#ifndef REVERSE_PROXY_SERVER_H
#define REVERSE_PROXY_SERVER_H

#include <Poco/Net/HTTPServer.h>
#include "Poco/Net/HTTPServerParams.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/Net/ConsoleCertificateHandler.h"
#include "Poco/Net/KeyConsoleHandler.h"
#include "Poco/Net/AcceptCertificateHandler.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/SharedPtr.h"
#include "Poco/ErrorHandler.h"
#include <iostream>

#include "HTTPSessionHandler.h"
#include "WebSocketSessionHandler.h"

// Custom error handler for SSL
class MyErrorHandler : public Poco::ErrorHandler {
public:
    void exception(const Poco::Exception& exc) override {
        std::cerr << "ErrorHandler: Poco Exception: " << exc.displayText() << std::endl;
        std::cerr << "ErrorHandler: Poco Exception: " << exc.what() << std::endl;
        std::cerr << "ErrorHandler: Poco Exception: " << exc.message() << std::endl;
    }
    void exception(const std::exception& exc) override {
        std::cerr << "ErrorHandler: Std Exception: " << exc.what() << std::endl;
    }
    void exception() override {
        std::cerr << "ErrorHandler: Unknown Exception." << std::endl;
    }
};

class ReverseProxyRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
    Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override {
        // Simple routing based on URI path
        if (request.getURI().find("/echo") == 0) { // For WebSocket path
            return new WebSocketSessionHandler("local.host", 8081, "/echo");
        } else { // For general HTTP requests
            return new HTTPSessionHandler("local.host", 8080);
        }
    }
};

class ReverseProxyServer : public Poco::Util::ServerApplication {
public:
    ReverseProxyServer();
    ~ReverseProxyServer();

protected:
    void initialize(Poco::Util::Application& self) override;
    void defineOptions(Poco::Util::OptionSet& options) override;
    void handleOption(const std::string& name, const std::string& value) override;
    int main(const std::vector<std::string>& args) override;

private:
    bool _helpRequested;
    std::string _certFile;
    std::string _keyFile;
    int _listenPort;
    MyErrorHandler _errorHandler;
};

#endif // REVERSE_PROXY_SERVER_H